home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / gnu / perl5000.zip / perl5000 / mg.c < prev    next >
C/C++ Source or Header  |  1994-10-17  |  23KB  |  1,251 lines

  1. /*    mg.c
  2.  *
  3.  *    Copyright (c) 1991-1994, Larry Wall
  4.  *
  5.  *    You may distribute under the terms of either the GNU General Public
  6.  *    License or the Artistic License, as specified in the README file.
  7.  *
  8.  */
  9.  
  10. /*
  11.  * "Sam sat on the ground and put his head in his hands.  'I wish I had never
  12.  * come here, and I don't want to see no more magic,' he said, and fell silent."
  13.  */
  14.  
  15. #include "EXTERN.h"
  16. #include "perl.h"
  17.  
  18. /* Omit -- it causes too much grief on mixed systems.
  19. #ifdef I_UNISTD
  20. # include <unistd.h>
  21. #endif
  22. */
  23.  
  24. void
  25. mg_magical(sv)
  26. SV* sv;
  27. {
  28.     MAGIC* mg;
  29.     for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
  30.     MGVTBL* vtbl = mg->mg_virtual;
  31.     if (vtbl) {
  32.         if (vtbl->svt_get && !(mg->mg_flags & MGf_GSKIP))
  33.         SvGMAGICAL_on(sv);
  34.         if (vtbl->svt_set)
  35.         SvSMAGICAL_on(sv);
  36.         if (!(SvFLAGS(sv) & (SVs_GMG|SVs_SMG)) || vtbl->svt_clear)
  37.         SvRMAGICAL_on(sv);
  38.     }
  39.     }
  40. }
  41.  
  42. int
  43. mg_get(sv)
  44. SV* sv;
  45. {
  46.     MAGIC* mg;
  47.     U32 savemagic = SvMAGICAL(sv) | SvREADONLY(sv);
  48.  
  49.     assert(SvGMAGICAL(sv));
  50.     SvMAGICAL_off(sv);
  51.     SvREADONLY_off(sv);
  52.     SvFLAGS(sv) |= (SvFLAGS(sv) & (SVp_IOK|SVp_NOK|SVp_POK)) >> PRIVSHIFT;
  53.  
  54.     for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
  55.     MGVTBL* vtbl = mg->mg_virtual;
  56.     if (!(mg->mg_flags & MGf_GSKIP) && vtbl && vtbl->svt_get) {
  57.         (*vtbl->svt_get)(sv, mg);
  58.         if (mg->mg_flags & MGf_GSKIP)
  59.         savemagic = 0;
  60.     }
  61.     }
  62.  
  63.     if (savemagic)
  64.     SvFLAGS(sv) |= savemagic;
  65.     else
  66.     mg_magical(sv);
  67.     if (SvGMAGICAL(sv))
  68.     SvFLAGS(sv) &= ~(SVf_IOK|SVf_NOK|SVf_POK);
  69.  
  70.     return 0;
  71. }
  72.  
  73. int
  74. mg_set(sv)
  75. SV* sv;
  76. {
  77.     MAGIC* mg;
  78.     MAGIC* nextmg;
  79.     U32 savemagic = SvMAGICAL(sv);
  80.  
  81.     SvMAGICAL_off(sv);
  82.  
  83.     for (mg = SvMAGIC(sv); mg; mg = nextmg) {
  84.     MGVTBL* vtbl = mg->mg_virtual;
  85.     nextmg = mg->mg_moremagic;    /* it may delete itself */
  86.     if (mg->mg_flags & MGf_GSKIP) {
  87.         mg->mg_flags &= ~MGf_GSKIP;    /* setting requires another read */
  88.         savemagic = 0;
  89.     }
  90.     if (vtbl && vtbl->svt_set)
  91.         (*vtbl->svt_set)(sv, mg);
  92.     }
  93.  
  94.     if (SvMAGIC(sv)) {
  95.     if (savemagic)
  96.         SvFLAGS(sv) |= savemagic;
  97.     else
  98.         mg_magical(sv);
  99.     if (SvGMAGICAL(sv))
  100.         SvFLAGS(sv) &= ~(SVf_IOK|SVf_NOK|SVf_POK);
  101.     }
  102.  
  103.     return 0;
  104. }
  105.  
  106. U32
  107. mg_len(sv)
  108. SV* sv;
  109. {
  110.     MAGIC* mg;
  111.     char *s;
  112.     STRLEN len;
  113.  
  114.     for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
  115.     MGVTBL* vtbl = mg->mg_virtual;
  116.     if (vtbl && vtbl->svt_len) {
  117.         U32 savemagic = SvMAGICAL(sv);
  118.  
  119.         SvMAGICAL_off(sv);
  120.         SvFLAGS(sv) |= (SvFLAGS(sv)&(SVp_IOK|SVp_NOK|SVp_POK)) >> PRIVSHIFT;
  121.  
  122.         /* omit MGf_GSKIP -- not changed here */
  123.         len = (*vtbl->svt_len)(sv, mg);
  124.  
  125.         SvFLAGS(sv) |= savemagic;
  126.         if (SvGMAGICAL(sv))
  127.         SvFLAGS(sv) &= ~(SVf_IOK|SVf_NOK|SVf_POK);
  128.  
  129.         return len;
  130.     }
  131.     }
  132.  
  133.     s = SvPV(sv, len);
  134.     return len;
  135. }
  136.  
  137. int
  138. mg_clear(sv)
  139. SV* sv;
  140. {
  141.     MAGIC* mg;
  142.     U32 savemagic = SvMAGICAL(sv);
  143.  
  144.     SvMAGICAL_off(sv);
  145.     SvFLAGS(sv) |= (SvFLAGS(sv) & (SVp_IOK|SVp_NOK|SVp_POK)) >> PRIVSHIFT;
  146.  
  147.     for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
  148.     MGVTBL* vtbl = mg->mg_virtual;
  149.     /* omit GSKIP -- never set here */
  150.     
  151.     if (vtbl && vtbl->svt_clear)
  152.         (*vtbl->svt_clear)(sv, mg);
  153.     }
  154.  
  155.     SvFLAGS(sv) |= savemagic;
  156.     if (SvGMAGICAL(sv))
  157.     SvFLAGS(sv) &= ~(SVf_IOK|SVf_NOK|SVf_POK);
  158.  
  159.     return 0;
  160. }
  161.  
  162. MAGIC*
  163. mg_find(sv, type)
  164. SV* sv;
  165. int type;
  166. {
  167.     MAGIC* mg;
  168.     for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
  169.     if (mg->mg_type == type)
  170.         return mg;
  171.     }
  172.     return 0;
  173. }
  174.  
  175. int
  176. mg_copy(sv, nsv, key, klen)
  177. SV* sv;
  178. SV* nsv;
  179. char *key;
  180. STRLEN klen;
  181. {
  182.     int count = 0;
  183.     MAGIC* mg;
  184.     for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
  185.     if (isUPPER(mg->mg_type)) {
  186.         sv_magic(nsv, mg->mg_obj, toLOWER(mg->mg_type), key, klen);
  187.         count++;
  188.     }
  189.     }
  190.     return count;
  191. }
  192.  
  193. int
  194. mg_free(sv)
  195. SV* sv;
  196. {
  197.     MAGIC* mg;
  198.     MAGIC* moremagic;
  199.     for (mg = SvMAGIC(sv); mg; mg = moremagic) {
  200.     MGVTBL* vtbl = mg->mg_virtual;
  201.     moremagic = mg->mg_moremagic;
  202.     if (vtbl && vtbl->svt_free)
  203.         (*vtbl->svt_free)(sv, mg);
  204.     if (mg->mg_ptr && mg->mg_type != 'g')
  205.         Safefree(mg->mg_ptr);
  206.     if (mg->mg_flags & MGf_REFCOUNTED)
  207.         SvREFCNT_dec(mg->mg_obj);
  208.     Safefree(mg);
  209.     }
  210.     SvMAGIC(sv) = 0;
  211.     return 0;
  212. }
  213.  
  214. #if !defined(NSIG) || defined(M_UNIX) || defined(M_XENIX)
  215. #include <signal.h>
  216. #endif
  217.  
  218. U32
  219. magic_len(sv, mg)
  220. SV *sv;
  221. MAGIC *mg;
  222. {
  223.     register I32 paren;
  224.     register char *s;
  225.     register I32 i;
  226.  
  227.     switch (*mg->mg_ptr) {
  228.     case '1': case '2': case '3': case '4':
  229.     case '5': case '6': case '7': case '8': case '9': case '&':
  230.     if (curpm) {
  231.         paren = atoi(mg->mg_ptr);
  232.       getparen:
  233.         if (curpm->op_pmregexp &&
  234.           paren <= curpm->op_pmregexp->nparens &&
  235.           (s = curpm->op_pmregexp->startp[paren]) ) {
  236.         i = curpm->op_pmregexp->endp[paren] - s;
  237.         if (i >= 0)
  238.             return i;
  239.         else
  240.             return 0;
  241.         }
  242.         else
  243.         return 0;
  244.     }
  245.     break;
  246.     case '+':
  247.     if (curpm) {
  248.         paren = curpm->op_pmregexp->lastparen;
  249.         if (!paren)
  250.         return 0;
  251.         goto getparen;
  252.     }
  253.     break;
  254.     case '`':
  255.     if (curpm) {
  256.         if (curpm->op_pmregexp &&
  257.           (s = curpm->op_pmregexp->subbeg) ) {
  258.         i = curpm->op_pmregexp->startp[0] - s;
  259.         if (i >= 0)
  260.             return i;
  261.         else
  262.             return 0;
  263.         }
  264.         else
  265.         return 0;
  266.     }
  267.     break;
  268.     case '\'':
  269.     if (curpm) {
  270.         if (curpm->op_pmregexp &&
  271.           (s = curpm->op_pmregexp->endp[0]) ) {
  272.         return (STRLEN) (curpm->op_pmregexp->subend - s);
  273.         }
  274.         else
  275.         return 0;
  276.     }
  277.     break;
  278.     case ',':
  279.     return (STRLEN)ofslen;
  280.     case '\\':
  281.     return (STRLEN)orslen;
  282.     }
  283.     magic_get(sv,mg);
  284.     if (!SvPOK(sv) && SvNIOK(sv))
  285.     sv_2pv(sv, &na);
  286.     if (SvPOK(sv))
  287.     return SvCUR(sv);
  288.     return 0;
  289. }
  290.  
  291. int
  292. magic_get(sv, mg)
  293. SV *sv;
  294. MAGIC *mg;
  295. {
  296.     register I32 paren;
  297.     register char *s;
  298.     register I32 i;
  299.  
  300.     switch (*mg->mg_ptr) {
  301.     case '\004':        /* ^D */
  302.     sv_setiv(sv,(I32)(debug & 32767));
  303.     break;
  304.     case '\006':        /* ^F */
  305.     sv_setiv(sv,(I32)maxsysfd);
  306.     break;
  307.     case '\010':        /* ^H */
  308.     sv_setiv(sv,(I32)hints);
  309.     break;
  310.     case '\t':            /* ^I */
  311.     if (inplace)
  312.         sv_setpv(sv, inplace);
  313.     else
  314.         sv_setsv(sv,&sv_undef);
  315.     break;
  316.     case '\020':        /* ^P */
  317.     sv_setiv(sv,(I32)perldb);
  318.     break;
  319.     case '\024':        /* ^T */
  320.     sv_setiv(sv,(I32)basetime);
  321.     break;
  322.     case '\027':        /* ^W */
  323.     sv_setiv(sv,(I32)dowarn);
  324.     break;
  325.     case '1': case '2': case '3': case '4':
  326.     case '5': case '6': case '7': case '8': case '9': case '&':
  327.     if (curpm) {
  328.         paren = atoi(GvENAME(mg->mg_obj));
  329.       getparen:
  330.         if (curpm->op_pmregexp &&
  331.           paren <= curpm->op_pmregexp->nparens &&
  332.           (s = curpm->op_pmregexp->startp[paren]) &&
  333.           curpm->op_pmregexp->endp[paren] ) {
  334.         i = curpm->op_pmregexp->endp[paren] - s;
  335.         if (i >= 0)
  336.             sv_setpvn(sv,s,i);
  337.         else
  338.             sv_setsv(sv,&sv_undef);
  339.         }
  340.         else
  341.         sv_setsv(sv,&sv_undef);
  342.     }
  343.     break;
  344.     case '+':
  345.     if (curpm) {
  346.         paren = curpm->op_pmregexp->lastparen;
  347.         if (paren)
  348.         goto getparen;
  349.         else
  350.         sv_setsv(sv,&sv_undef);
  351.     }
  352.     break;
  353.     case '`':
  354.     if (curpm) {
  355.         if (curpm->op_pmregexp &&
  356.           (s = curpm->op_pmregexp->subbeg) ) {
  357.         i = curpm->op_pmregexp->startp[0] - s;
  358.         if (i >= 0)
  359.             sv_setpvn(sv,s,i);
  360.         else
  361.             sv_setpvn(sv,"",0);
  362.         }
  363.         else
  364.         sv_setpvn(sv,"",0);
  365.     }
  366.     break;
  367.     case '\'':
  368.     if (curpm) {
  369.         if (curpm->op_pmregexp &&
  370.           (s = curpm->op_pmregexp->endp[0]) ) {
  371.         sv_setpvn(sv,s, curpm->op_pmregexp->subend - s);
  372.         }
  373.         else
  374.         sv_setpvn(sv,"",0);
  375.     }
  376.     break;
  377.     case '.':
  378. #ifndef lint
  379.     if (GvIO(last_in_gv)) {
  380.         sv_setiv(sv,(I32)IoLINES(GvIO(last_in_gv)));
  381.     }
  382. #endif
  383.     break;
  384.     case '?':
  385.     sv_setiv(sv,(I32)statusvalue);
  386.     break;
  387.     case '^':
  388.     s = IoTOP_NAME(GvIOp(defoutgv));
  389.     if (s)
  390.         sv_setpv(sv,s);
  391.     else {
  392.         sv_setpv(sv,GvENAME(defoutgv));
  393.         sv_catpv(sv,"_TOP");
  394.     }
  395.     break;
  396.     case '~':
  397.     s = IoFMT_NAME(GvIOp(defoutgv));
  398.     if (!s)
  399.         s = GvENAME(defoutgv);
  400.     sv_setpv(sv,s);
  401.     break;
  402. #ifndef lint
  403.     case '=':
  404.     sv_setiv(sv,(I32)IoPAGE_LEN(GvIOp(defoutgv)));
  405.     break;
  406.     case '-':
  407.     sv_setiv(sv,(I32)IoLINES_LEFT(GvIOp(defoutgv)));
  408.     break;
  409.     case '%':
  410.     sv_setiv(sv,(I32)IoPAGE(GvIOp(defoutgv)));
  411.     break;
  412. #endif
  413.     case ':':
  414.     break;
  415.     case '/':
  416.     break;
  417.     case '[':
  418.     sv_setiv(sv,(I32)curcop->cop_arybase);
  419.     break;
  420.     case '|':
  421.     sv_setiv(sv, (IoFLAGS(GvIOp(defoutgv)) & IOf_FLUSH) != 0 );
  422.     break;
  423.     case ',':
  424.     sv_setpvn(sv,ofs,ofslen);
  425.     break;
  426.     case '\\':
  427.     sv_setpvn(sv,ors,orslen);
  428.     break;
  429.     case '#':
  430.     sv_setpv(sv,ofmt);
  431.     break;
  432.     case '!':
  433.     sv_setnv(sv,(double)errno);
  434.     sv_setpv(sv, errno ? Strerror(errno) : "");
  435.     SvNOK_on(sv);    /* what a wonderful hack! */
  436.     break;
  437.     case '<':
  438.     sv_setiv(sv,(I32)uid);
  439.     break;
  440.     case '>':
  441.     sv_setiv(sv,(I32)euid);
  442.     break;
  443.     case '(':
  444.     s = buf;
  445.     (void)sprintf(s,"%d",(int)gid);
  446.     goto add_groups;
  447.     case ')':
  448.     s = buf;
  449.     (void)sprintf(s,"%d",(int)egid);
  450.       add_groups:
  451.     while (*s) s++;
  452. #ifdef HAS_GETGROUPS
  453. #ifndef NGROUPS
  454. #define NGROUPS 32
  455. #endif
  456.     {
  457.         Groups_t gary[NGROUPS];
  458.  
  459.         i = getgroups(NGROUPS,gary);
  460.         while (--i >= 0) {
  461.         (void)sprintf(s," %ld", (long)gary[i]);
  462.         while (*s) s++;
  463.         }
  464.     }
  465. #endif
  466.     sv_setpv(sv,buf);
  467.     break;
  468.     case '*':
  469.     break;
  470.     case '0':
  471.     break;
  472.     }
  473.     return 0;
  474. }
  475.  
  476. int
  477. magic_getuvar(sv, mg)
  478. SV *sv;
  479. MAGIC *mg;
  480. {
  481.     struct ufuncs *uf = (struct ufuncs *)mg->mg_ptr;
  482.  
  483.     if (uf && uf->uf_val)
  484.     (*uf->uf_val)(uf->uf_index, sv);
  485.     return 0;
  486. }
  487.  
  488. int
  489. magic_setenv(sv,mg)
  490. SV* sv;
  491. MAGIC* mg;
  492. {
  493.     register char *s;
  494.     STRLEN len;
  495.     I32 i;
  496.     s = SvPV(sv,len);
  497.     my_setenv(mg->mg_ptr,s);
  498. #ifdef DYNAMIC_ENV_FETCH
  499.      /* We just undefd an environment var.  Is a replacement */
  500.      /* waiting in the wings? */
  501.     if (!len) {
  502.     SV **envsvp;
  503.     if (envsvp = hv_fetch(GvHVn(envgv),mg->mg_ptr,mg->mg_len,FALSE))
  504.         s = SvPV(*envsvp,len);
  505.     }
  506. #endif
  507.                 /* And you'll never guess what the dog had */
  508.                 /*   in its mouth... */
  509.     if (tainting) {
  510.     if (s && strEQ(mg->mg_ptr,"PATH")) {
  511.         char *strend = s + len;
  512.  
  513.         while (s < strend) {
  514.         s = cpytill(tokenbuf,s,strend,':',&i);
  515.         s++;
  516.         if (*tokenbuf != '/'
  517.           || (Stat(tokenbuf,&statbuf) && (statbuf.st_mode & 2)) )
  518.             MgTAINTEDDIR_on(mg);
  519.         }
  520.     }
  521.     }
  522.     return 0;
  523. }
  524.  
  525. int
  526. magic_clearenv(sv,mg)
  527. SV* sv;
  528. MAGIC* mg;
  529. {
  530.     my_setenv(mg->mg_ptr,Nullch);
  531.     return 0;
  532. }
  533.  
  534. int
  535. magic_setsig(sv,mg)
  536. SV* sv;
  537. MAGIC* mg;
  538. {
  539.     register char *s;
  540.     I32 i;
  541.  
  542.     i = whichsig(mg->mg_ptr);    /* ...no, a brick */
  543.     if (!i && (dowarn || strEQ(mg->mg_ptr,"ALARM")))
  544.     warn("No such signal: SIG%s", mg->mg_ptr);
  545.     if (SvTYPE(sv) == SVt_PVGV || SvROK(sv)) {
  546.     (void)signal(i,sighandler);
  547.     return 0;
  548.     }
  549.     s = SvPV_force(sv,na);
  550.     if (strEQ(s,"IGNORE"))
  551. #ifndef lint
  552.     (void)signal(i,SIG_IGN);
  553. #else
  554.     ;
  555. #endif
  556.     else if (strEQ(s,"DEFAULT") || !*s)
  557.     (void)signal(i,SIG_DFL);
  558.     else {
  559.     (void)signal(i,sighandler);
  560.     if (!strchr(s,':') && !strchr(s,'\'')) {
  561.         sprintf(tokenbuf, "main::%s",s);
  562.         sv_setpv(sv,tokenbuf);
  563.     }
  564.     }
  565.     return 0;
  566. }
  567.  
  568. int
  569. magic_setisa(sv,mg)
  570. SV* sv;
  571. MAGIC* mg;
  572. {
  573.     sub_generation++;
  574.     return 0;
  575. }
  576.  
  577. #ifdef OVERLOAD
  578.  
  579. int
  580. magic_setamagic(sv,mg)
  581. SV* sv;
  582. MAGIC* mg;
  583. {
  584.     /* HV_badAMAGIC_on(Sv_STASH(sv)); */
  585.     amagic_generation++;
  586.  
  587.     return 0;
  588. }
  589. #endif /* OVERLOAD */
  590.  
  591. static int
  592. magic_methpack(sv,mg,meth)
  593. SV* sv;
  594. MAGIC* mg;
  595. char *meth;
  596. {
  597.     dSP;
  598.  
  599.     ENTER;
  600.     SAVETMPS;
  601.     PUSHMARK(sp);
  602.     EXTEND(sp, 2);
  603.     PUSHs(mg->mg_obj);
  604.     if (mg->mg_ptr)
  605.     PUSHs(sv_2mortal(newSVpv(mg->mg_ptr, mg->mg_len)));
  606.     else if (mg->mg_type == 'p')
  607.     PUSHs(sv_2mortal(newSViv(mg->mg_len)));
  608.     PUTBACK;
  609.  
  610.     if (perl_call_method(meth, G_SCALAR))
  611.     sv_setsv(sv, *stack_sp--);
  612.  
  613.     FREETMPS;
  614.     LEAVE;
  615.     return 0;
  616. }
  617.  
  618. int
  619. magic_getpack(sv,mg)
  620. SV* sv;
  621. MAGIC* mg;
  622. {
  623.     magic_methpack(sv,mg,"FETCH");
  624.     if (mg->mg_ptr)
  625.     mg->mg_flags |= MGf_GSKIP;
  626.     return 0;
  627. }
  628.  
  629. int
  630. magic_setpack(sv,mg)
  631. SV* sv;
  632. MAGIC* mg;
  633. {
  634.     dSP;
  635.  
  636.     PUSHMARK(sp);
  637.     EXTEND(sp, 3);
  638.     PUSHs(mg->mg_obj);
  639.     if (mg->mg_ptr)
  640.     PUSHs(sv_2mortal(newSVpv(mg->mg_ptr, mg->mg_len)));
  641.     else if (mg->mg_type == 'p')
  642.     PUSHs(sv_2mortal(newSViv(mg->mg_len)));
  643.     PUSHs(sv);
  644.     PUTBACK;
  645.  
  646.     perl_call_method("STORE", G_SCALAR|G_DISCARD);
  647.  
  648.     return 0;
  649. }
  650.  
  651. int
  652. magic_clearpack(sv,mg)
  653. SV* sv;
  654. MAGIC* mg;
  655. {
  656.     return magic_methpack(sv,mg,"DELETE");
  657. }
  658.  
  659. int magic_wipepack(sv,mg)
  660. SV* sv;
  661. MAGIC* mg;
  662. {
  663.     dSP;
  664.  
  665.     PUSHMARK(sp);
  666.     XPUSHs(mg->mg_obj);
  667.     PUTBACK;
  668.  
  669.     perl_call_method("CLEAR", G_SCALAR|G_DISCARD);
  670.  
  671.     return 0;
  672. }
  673.  
  674. int
  675. magic_nextpack(sv,mg,key)
  676. SV* sv;
  677. MAGIC* mg;
  678. SV* key;
  679. {
  680.     dSP;
  681.     char *meth = SvOK(key) ? "NEXTKEY" : "FIRSTKEY";
  682.  
  683.     ENTER;
  684.     SAVETMPS;
  685.     PUSHMARK(sp);
  686.     EXTEND(sp, 2);
  687.     PUSHs(mg->mg_obj);
  688.     if (SvOK(key))
  689.     PUSHs(key);
  690.     PUTBACK;
  691.  
  692.     if (perl_call_method(meth, G_SCALAR))
  693.     sv_setsv(key, *stack_sp--);
  694.  
  695.     FREETMPS;
  696.     LEAVE;
  697.     return 0;
  698. }
  699.  
  700. int
  701. magic_existspack(sv,mg)
  702. SV* sv;
  703. MAGIC* mg;
  704. {
  705.     return magic_methpack(sv,mg,"EXISTS");
  706.  
  707. int
  708. magic_setdbline(sv,mg)
  709. SV* sv;
  710. MAGIC* mg;
  711. {
  712.     OP *o;
  713.     I32 i;
  714.     GV* gv;
  715.     SV** svp;
  716.  
  717.     gv = DBline;
  718.     i = SvTRUE(sv);
  719.     svp = av_fetch(GvAV(gv),atoi(mg->mg_ptr), FALSE);
  720.     if (svp && SvIOKp(*svp) && (o = (OP*)SvSTASH(*svp)))
  721.     o->op_private = i;
  722.     else
  723.     warn("Can't break at that line\n");
  724.     return 0;
  725. }
  726.  
  727. int
  728. magic_getarylen(sv,mg)
  729. SV* sv;
  730. MAGIC* mg;
  731. {
  732.     sv_setiv(sv, AvFILL((AV*)mg->mg_obj) + curcop->cop_arybase);
  733.     return 0;
  734. }
  735.  
  736. int
  737. magic_setarylen(sv,mg)
  738. SV* sv;
  739. MAGIC* mg;
  740. {
  741.     av_fill((AV*)mg->mg_obj, SvIV(sv) - curcop->cop_arybase);
  742.     return 0;
  743. }
  744.  
  745. int
  746. magic_getpos(sv,mg)
  747. SV* sv;
  748. MAGIC* mg;
  749. {
  750.     SV* lsv = LvTARG(sv);
  751.     
  752.     if (SvTYPE(lsv) >= SVt_PVMG && SvMAGIC(lsv)) {
  753.     mg = mg_find(lsv, 'g');
  754.     if (mg && mg->mg_len >= 0) {
  755.         sv_setiv(sv, mg->mg_len + curcop->cop_arybase);
  756.         return 0;
  757.     }
  758.     }
  759.     (void)SvOK_off(sv);
  760.     return 0;
  761. }
  762.  
  763. int
  764. magic_setpos(sv,mg)
  765. SV* sv;
  766. MAGIC* mg;
  767. {
  768.     SV* lsv = LvTARG(sv);
  769.     SSize_t pos;
  770.     STRLEN len;
  771.  
  772.     mg = 0;
  773.     
  774.     if (SvTYPE(lsv) >= SVt_PVMG && SvMAGIC(lsv))
  775.     mg = mg_find(lsv, 'g');
  776.     if (!mg) {
  777.     if (!SvOK(sv))
  778.         return 0;
  779.     sv_magic(lsv, (SV*)0, 'g', Nullch, 0);
  780.     mg = mg_find(lsv, 'g');
  781.     }
  782.     else if (!SvOK(sv)) {
  783.     mg->mg_len = -1;
  784.     return 0;
  785.     }
  786.     len = SvPOK(lsv) ? SvCUR(lsv) : sv_len(lsv);
  787.  
  788.     pos = SvIV(sv) - curcop->cop_arybase;
  789.     if (pos < 0) {
  790.     pos += len;
  791.     if (pos < 0)
  792.         pos = 0;
  793.     }
  794.     else if (pos > len)
  795.     pos = len;
  796.     mg->mg_len = pos;
  797.  
  798.     return 0;
  799. }
  800.  
  801. int
  802. magic_getglob(sv,mg)
  803. SV* sv;
  804. MAGIC* mg;
  805. {
  806.     gv_efullname(sv,((GV*)sv));/* a gv value, be nice */
  807.     return 0;
  808. }
  809.  
  810. int
  811. magic_setglob(sv,mg)
  812. SV* sv;
  813. MAGIC* mg;
  814. {
  815.     register char *s;
  816.     GV* gv;
  817.  
  818.     if (!SvOK(sv))
  819.     return 0;
  820.     s = SvPV(sv, na);
  821.     if (*s == '*' && s[1])
  822.     s++;
  823.     gv = gv_fetchpv(s,TRUE, SVt_PVGV);
  824.     if (sv == (SV*)gv)
  825.     return 0;
  826.     if (GvGP(sv))
  827.     gp_free(sv);
  828.     GvGP(sv) = gp_ref(GvGP(gv));
  829.     if (!GvAV(gv))
  830.     gv_AVadd(gv);
  831.     if (!GvHV(gv))
  832.     gv_HVadd(gv);
  833.     if (!GvIOp(gv))
  834.     GvIOp(gv) = newIO();
  835.     return 0;
  836. }
  837.  
  838. int
  839. magic_setsubstr(sv,mg)
  840. SV* sv;
  841. MAGIC* mg;
  842. {
  843.     STRLEN len;
  844.     char *tmps = SvPV(sv,len);
  845.     sv_insert(LvTARG(sv),LvTARGOFF(sv),LvTARGLEN(sv), tmps, len);
  846.     return 0;
  847. }
  848.  
  849. int
  850. magic_gettaint(sv,mg)
  851. SV* sv;
  852. MAGIC* mg;
  853. {
  854.     tainted = TRUE;
  855.     return 0;
  856. }
  857.  
  858. int
  859. magic_settaint(sv,mg)
  860. SV* sv;
  861. MAGIC* mg;
  862. {
  863.     if (!tainted) {
  864.     if (!SvMAGICAL(sv))
  865.         SvMAGICAL_on(sv);
  866.     sv_unmagic(sv, 't');
  867.     }
  868.     return 0;
  869. }
  870.  
  871. int
  872. magic_setvec(sv,mg)
  873. SV* sv;
  874. MAGIC* mg;
  875. {
  876.     do_vecset(sv);    /* XXX slurp this routine */
  877.     return 0;
  878. }
  879.  
  880. int
  881. magic_setmglob(sv,mg)
  882. SV* sv;
  883. MAGIC* mg;
  884. {
  885.     mg->mg_len = -1;
  886.     return 0;
  887. }
  888.  
  889. int
  890. magic_setbm(sv,mg)
  891. SV* sv;
  892. MAGIC* mg;
  893. {
  894.     sv_unmagic(sv, 'B');
  895.     SvVALID_off(sv);
  896.     return 0;
  897. }
  898.  
  899. int
  900. magic_setuvar(sv,mg)
  901. SV* sv;
  902. MAGIC* mg;
  903. {
  904.     struct ufuncs *uf = (struct ufuncs *)mg->mg_ptr;
  905.  
  906.     if (uf && uf->uf_set)
  907.     (*uf->uf_set)(uf->uf_index, sv);
  908.     return 0;
  909. }
  910.  
  911. int
  912. magic_set(sv,mg)
  913. SV* sv;
  914. MAGIC* mg;
  915. {
  916.     register char *s;
  917.     I32 i;
  918.     STRLEN len;
  919.     switch (*mg->mg_ptr) {
  920.     case '\004':    /* ^D */
  921.     debug = (SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)) | 0x80000000;
  922.     DEBUG_x(dump_all());
  923.     break;
  924.     case '\006':    /* ^F */
  925.     maxsysfd = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
  926.     break;
  927.     case '\010':    /* ^H */
  928.     hints = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
  929.     break;
  930.     case '\t':    /* ^I */
  931.     if (inplace)
  932.         Safefree(inplace);
  933.     if (SvOK(sv))
  934.         inplace = savepv(SvPV(sv,na));
  935.     else
  936.         inplace = Nullch;
  937.     break;
  938.     case '\020':    /* ^P */
  939.     i = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
  940.     if (i != perldb) {
  941.         if (perldb)
  942.         oldlastpm = curpm;
  943.         else
  944.         curpm = oldlastpm;
  945.     }
  946.     perldb = i;
  947.     break;
  948.     case '\024':    /* ^T */
  949.     basetime = (Time_t)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
  950.     break;
  951.     case '\027':    /* ^W */
  952.     dowarn = (bool)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
  953.     break;
  954.     case '.':
  955.     if (localizing)
  956.         save_sptr((SV**)&last_in_gv);
  957.     else if (SvOK(sv))
  958.         IoLINES(GvIOp(last_in_gv)) = (long)SvIV(sv);
  959.     break;
  960.     case '^':
  961.     Safefree(IoTOP_NAME(GvIOp(defoutgv)));
  962.     IoTOP_NAME(GvIOp(defoutgv)) = s = savepv(SvPV(sv,na));
  963.     IoTOP_GV(GvIOp(defoutgv)) = gv_fetchpv(s,TRUE, SVt_PVIO);
  964.     break;
  965.     case '~':
  966.     Safefree(IoFMT_NAME(GvIOp(defoutgv)));
  967.     IoFMT_NAME(GvIOp(defoutgv)) = s = savepv(SvPV(sv,na));
  968.     IoFMT_GV(GvIOp(defoutgv)) = gv_fetchpv(s,TRUE, SVt_PVIO);
  969.     break;
  970.     case '=':
  971.     IoPAGE_LEN(GvIOp(defoutgv)) = (long)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
  972.     break;
  973.     case '-':
  974.     IoLINES_LEFT(GvIOp(defoutgv)) = (long)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
  975.     if (IoLINES_LEFT(GvIOp(defoutgv)) < 0L)
  976.         IoLINES_LEFT(GvIOp(defoutgv)) = 0L;
  977.     break;
  978.     case '%':
  979.     IoPAGE(GvIOp(defoutgv)) = (long)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
  980.     break;
  981.     case '|':
  982.     IoFLAGS(GvIOp(defoutgv)) &= ~IOf_FLUSH;
  983.     if ((SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)) != 0) {
  984.         IoFLAGS(GvIOp(defoutgv)) |= IOf_FLUSH;
  985.     }
  986.     break;
  987.     case '*':
  988.     i = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
  989.     multiline = (i != 0);
  990.     break;
  991.     case '/':
  992.     if (SvOK(sv)) {
  993.         nrs = rs = SvPV_force(sv,rslen);
  994.         nrslen = rslen;
  995.         if (rspara = !rslen) {
  996.         nrs = rs = "\n\n";
  997.         nrslen = rslen = 2;
  998.         }
  999.         nrschar = rschar = rs[rslen - 1];
  1000.     }
  1001.     else {
  1002.         nrschar = rschar = 0777;    /* fake a non-existent char */
  1003.         nrslen = rslen = 1;
  1004.     }
  1005.     break;
  1006.     case '\\':
  1007.     if (ors)
  1008.         Safefree(ors);
  1009.     ors = savepv(SvPV(sv,orslen));
  1010.     break;
  1011.     case ',':
  1012.     if (ofs)
  1013.         Safefree(ofs);
  1014.     ofs = savepv(SvPV(sv, ofslen));
  1015.     break;
  1016.     case '#':
  1017.     if (ofmt)
  1018.         Safefree(ofmt);
  1019.     ofmt = savepv(SvPV(sv,na));
  1020.     break;
  1021.     case '[':
  1022.     compiling.cop_arybase = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
  1023.     break;
  1024.     case '?':
  1025.     statusvalue = U_S(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
  1026.     break;
  1027.     case '!':
  1028.     errno = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);        /* will anyone ever use this? */
  1029.     break;
  1030.     case '<':
  1031.     uid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
  1032.     if (delaymagic) {
  1033.         delaymagic |= DM_RUID;
  1034.         break;                /* don't do magic till later */
  1035.     }
  1036. #ifdef HAS_SETRUID
  1037.     (void)setruid((Uid_t)uid);
  1038. #else
  1039. #ifdef HAS_SETREUID
  1040.     (void)setreuid((Uid_t)uid, (Uid_t)-1);
  1041. #ifdef HAS_SETRESUID
  1042.       (void)setresuid((Uid_t)uid, (Uid_t)-1, (Uid_t)-1);
  1043. #else
  1044.     if (uid == euid)        /* special case $< = $> */
  1045.         (void)setuid(uid);
  1046.     else {
  1047.         uid = (I32)getuid();
  1048.         croak("setruid() not implemented");
  1049.     }
  1050. #endif
  1051. #endif
  1052. #endif
  1053.     uid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
  1054.     tainting |= (euid != uid || egid != gid);
  1055.     break;
  1056.     case '>':
  1057.     euid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
  1058.     if (delaymagic) {
  1059.         delaymagic |= DM_EUID;
  1060.         break;                /* don't do magic till later */
  1061.     }
  1062. #ifdef HAS_SETEUID
  1063.     (void)seteuid((Uid_t)euid);
  1064. #else
  1065. #ifdef HAS_SETREUID
  1066.     (void)setreuid((Uid_t)-1, (Uid_t)euid);
  1067. #else
  1068. #ifdef HAS_SETRESUID
  1069.     (void)setresuid((Uid_t)-1, (Uid_t)euid, (Uid_t)-1);
  1070. #else
  1071.     if (euid == uid)        /* special case $> = $< */
  1072.         setuid(euid);
  1073.     else {
  1074.         euid = (I32)geteuid();
  1075.         croak("seteuid() not implemented");
  1076.     }
  1077. #endif
  1078. #endif
  1079. #endif
  1080.     euid = (I32)geteuid();
  1081.     tainting |= (euid != uid || egid != gid);
  1082.     break;
  1083.     case '(':
  1084.     gid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
  1085.     if (delaymagic) {
  1086.         delaymagic |= DM_RGID;
  1087.         break;                /* don't do magic till later */
  1088.     }
  1089. #ifdef HAS_SETRGID
  1090.     (void)setrgid((Gid_t)gid);
  1091. #else
  1092. #ifdef HAS_SETREGID
  1093.     (void)setregid((Gid_t)gid, (Gid_t)-1);
  1094. #else
  1095. #ifdef HAS_SETRESGID
  1096.       (void)setresgid((Gid_t)gid, (Gid_t)-1, (Gid_t) 1);
  1097. #else
  1098.     if (gid == egid)            /* special case $( = $) */
  1099.         (void)setgid(gid);
  1100.     else
  1101.         croak("setrgid() not implemented");
  1102. #endif
  1103. #endif
  1104. #endif
  1105.     gid = (I32)getgid();
  1106.     tainting |= (euid != uid || egid != gid);
  1107.     break;
  1108.     case ')':
  1109.     egid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
  1110.     if (delaymagic) {
  1111.         delaymagic |= DM_EGID;
  1112.         break;                /* don't do magic till later */
  1113.     }
  1114. #ifdef HAS_SETEGID
  1115.     (void)setegid((Gid_t)egid);
  1116. #else
  1117. #ifdef HAS_SETREGID
  1118.     (void)setregid((Gid_t)-1, (Gid_t)egid);
  1119. #else
  1120. #ifdef HAS_SETRESGID
  1121.     (void)setresgid((Gid_t)-1, (Gid_t)egid, (Gid_t)-1);
  1122. #else
  1123.     if (egid == gid)            /* special case $) = $( */
  1124.         (void)setgid(egid);
  1125.     else
  1126.         croak("setegid() not implemented");
  1127. #endif
  1128. #endif
  1129. #endif
  1130.     egid = (I32)getegid();
  1131.     tainting |= (euid != uid || egid != gid);
  1132.     break;
  1133.     case ':':
  1134.     chopset = SvPV_force(sv,na);
  1135.     break;
  1136.     case '0':
  1137.     if (!origalen) {
  1138.         s = origargv[0];
  1139.         s += strlen(s);
  1140.         /* See if all the arguments are contiguous in memory */
  1141.         for (i = 1; i < origargc; i++) {
  1142.         if (origargv[i] == s + 1)
  1143.             s += strlen(++s);    /* this one is ok too */
  1144.         }
  1145.         if (origenviron[0] == s + 1) {    /* can grab env area too? */
  1146.         my_setenv("NoNeSuCh", Nullch);
  1147.                         /* force copy of environment */
  1148.         for (i = 0; origenviron[i]; i++)
  1149.             if (origenviron[i] == s + 1)
  1150.             s += strlen(++s);
  1151.         }
  1152.         origalen = s - origargv[0];
  1153.     }
  1154.     s = SvPV_force(sv,len);
  1155.     i = len;
  1156.     if (i >= origalen) {
  1157.         i = origalen;
  1158.         SvCUR_set(sv, i);
  1159.         *SvEND(sv) = '\0';
  1160.         Copy(s, origargv[0], i, char);
  1161.     }
  1162.     else {
  1163.         Copy(s, origargv[0], i, char);
  1164.         s = origargv[0]+i;
  1165.         *s++ = '\0';
  1166.         while (++i < origalen)
  1167.         *s++ = ' ';
  1168.         s = origargv[0]+i;
  1169.         for (i = 1; i < origargc; i++)
  1170.         origargv[i] = Nullch;
  1171.     }
  1172.     break;
  1173.     }
  1174.     return 0;
  1175. }
  1176.  
  1177. I32
  1178. whichsig(sig)
  1179. char *sig;
  1180. {
  1181.     register char **sigv;
  1182.  
  1183.     for (sigv = sig_name+1; *sigv; sigv++)
  1184.     if (strEQ(sig,*sigv))
  1185.         return sigv - sig_name;
  1186. #ifdef SIGCLD
  1187.     if (strEQ(sig,"CHLD"))
  1188.     return SIGCLD;
  1189. #endif
  1190. #ifdef SIGCHLD
  1191.     if (strEQ(sig,"CLD"))
  1192.     return SIGCHLD;
  1193. #endif
  1194.     return 0;
  1195. }
  1196.  
  1197. VOIDRET
  1198. sighandler(sig)
  1199. int sig;
  1200. {
  1201.     dSP;
  1202.     GV *gv;
  1203.     HV *st;
  1204.     SV *sv;
  1205.     CV *cv;
  1206.     AV *oldstack;
  1207.  
  1208. #ifdef OS2        /* or anybody else who requires SIG_ACK */
  1209.     signal(sig, SIG_ACK);
  1210. #endif
  1211.  
  1212.     cv = sv_2cv(*hv_fetch(GvHVn(siggv),sig_name[sig],strlen(sig_name[sig]),
  1213.               TRUE),
  1214.         &st, &gv, TRUE);
  1215.     if (!cv || !CvROOT(cv) &&
  1216.     *sig_name[sig] == 'C' && instr(sig_name[sig],"LD")) {
  1217.     
  1218.     if (sig_name[sig][1] == 'H')
  1219.         cv = sv_2cv(*hv_fetch(GvHVn(siggv),"CLD",3,TRUE),
  1220.             &st, &gv, TRUE);
  1221.     else
  1222.         cv = sv_2cv(*hv_fetch(GvHVn(siggv),"CHLD",4,TRUE),
  1223.             &st, &gv, TRUE);
  1224.     /* gag */
  1225.     }
  1226.     if (!cv || !CvROOT(cv)) {
  1227.     if (dowarn)
  1228.         warn("SIG%s handler \"%s\" not defined.\n",
  1229.         sig_name[sig], GvENAME(gv) );
  1230.     return;
  1231.     }
  1232.  
  1233.     oldstack = stack;
  1234.     if (stack != signalstack)
  1235.     AvFILL(signalstack) = 0;
  1236.     SWITCHSTACK(stack, signalstack);
  1237.  
  1238.     sv = sv_newmortal();
  1239.     sv_setpv(sv,sig_name[sig]);
  1240.     PUSHMARK(sp);
  1241.     PUSHs(sv);
  1242.     PUTBACK;
  1243.  
  1244.     perl_call_sv((SV*)cv, G_DISCARD);
  1245.  
  1246.     SWITCHSTACK(signalstack, oldstack);
  1247.  
  1248.     return;
  1249. }
  1250.